package com.kly.user.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.fqgj.common.api.Response;
import com.fqgj.common.utils.StringUtils;
import com.fqgj.log.factory.LogFactory;
import com.fqgj.log.interfaces.Log;
import com.fqgj.log.util.JsonUtil;
import com.google.common.collect.Maps;
import com.kly.user.db.dao.UserAdjustMappingDao;
import com.kly.user.db.dao.UserAdjustReportDao;
import com.kly.user.db.dao.UserDao;
import com.kly.user.db.dao.UserTaskDetailDao;
import com.kly.user.db.entity.UserAdjustMappingEntity;
import com.kly.user.db.entity.UserAdjustReportEntity;
import com.kly.user.db.entity.UserAppflyersMappingEntity;
import com.kly.user.db.entity.UserEntity;
import com.kly.user.dto.AdJustUserMappingReq;
import com.kly.user.dto.StoreReportReq;
import com.kly.user.enums.AdjustEventDefType;
import com.kly.user.enums.AppCodeEnum;
import com.kly.user.mapper.UserAdjustMappingMapper;
import com.kly.user.service.AdjustService;
import com.kly.user.task.enums.TaskStatusEnum;
import com.kly.user.task.enums.TaskTypeEnum;
import com.kly.user.utils.LittleOrangeService;
import com.robert.vesta.util.IdUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Service("adjustService")
public class AdjustServiceImpl implements AdjustService {
    private static Log logger = LogFactory.getLog(AdjustServiceImpl.class);
    @NacosValue(value = "${is.prod.env}", autoRefreshed = true)
    private boolean isTestEnv;
    @NacosValue(value = "${adjust.environment}", autoRefreshed = true)
    private String environment;
    @NacosValue(value = "${adjust.token:e85aefe121692886acb0b2c6c4bee449}", autoRefreshed = true)
    private String authToken;
    @NacosValue(value = "${is.review:true}", autoRefreshed = true)
    private boolean isReview;
    @Resource
    UserAdjustMappingDao userAdjustMappingDao;
    @Resource
    UserTaskDetailDao userTaskDetailDao;
    @Resource
    UserAdjustReportDao userAdjustReportDao;
    @Resource
    UserDao userDao;
    @Resource
    UserAdjustMappingMapper userAdjustMappingMapper;
    /**
     * adjust api 地址
     */
    private static final String apiUrl = "https://s2s.adjust.com/";
    /**
     * 报告应用内事件方法
     */
    private static final String eventMethod = "event";
//    /**
//     * Adjust 报告广告收入数据方法
//     */
//    private static final String revenueMethod = "ad_revenue";


    @Override
    public Response storeAppsFlyerReport(StoreReportReq storeReportReq) {
        String reportCode = IdUtils.genId() + "";
        UserAdjustReportEntity reportEntity = new UserAdjustReportEntity();
        reportEntity.setReportTime(DateUtil.format(new Date(), DatePattern.NORM_DATETIME_FORMATTER));
        reportEntity.setReportContent(storeReportReq.getReportContent());
        reportEntity.setReportCode(reportCode);
//        reportEntity.setDataFrom(fromPushApi);
        userAdjustReportDao.insert(reportEntity);
        return null;
    }

    @Async
    @Override
    public Response asyncTraceEvent(AdjustEventDefType eventType, Map<String, Object> pushData) {
        final String userCode = (String) pushData.get("userCode");
        String appCode = AppCodeEnum.MEBOO.getAppCode();

        if (isTestEnv) {
            logger.info("======测试环境不予推送======");
            return Response.ok();
        }

        String method = eventMethod;
//        if (AdjustEventDefType.D0_Purchase.equals(eventType) || AdjustEventDefType.Purchase.equals(eventType)) {
//            method = revenueMethod;
//        }
        if (pushData.containsKey("appCode") && pushData.get("appCode") != null) {
            appCode = (String) pushData.get("appCode");
        }

        // 封装请求url
        StringBuilder sb = new StringBuilder(apiUrl + method + "?s2s=1&app_token=o7c4dqoa1q0w&event_token=");

        JSONObject req = new JSONObject();
        try {
            logger.info("PushDataToAppsFlyerBegin, pushType:{}, pushData:{}", eventType.getEventCode(), JSONObject.toJSONString(pushData));

            UserAdjustMappingEntity userMapping = userAdjustMappingDao.getUserMapping(userCode);
            if (Objects.isNull(userMapping) || StringUtils.isEmpty(userMapping.getAdId())) {
                logger.error("ADjustIdNotExists, pushType:{}, pushData:{}", eventType.getEventCode(), JsonUtil.toJson(pushData));
                return Response.ok();
            }

            sb.append(eventType.getValue());
            sb.append("&adid=").append(userMapping.getAdId());
            sb.append("&created_at_unix=").append(System.currentTimeMillis() / 1000);
            if (AdjustEventDefType.D0_Purchase.equals(eventType) || AdjustEventDefType.Purchase.equals(eventType)) {
                sb.append("&revenue=").append(pushData.get("amount"));
                sb.append("&currency=USD");
//                sb.append("callback_params=");
            }
            sb.append("&environment=").append(environment);

            logger.info("PushDataToAdjustSuccess, body:{}", req.toJSONString());
            if (isReview) {
                userTaskDetailDao.addHasExecutedTask(TaskTypeEnum.PUSH_DATA_TO_AD_JUST, TaskStatusEnum.REVIEW, JSONObject.toJSONString(pushData), "Waiting", eventType.getEventCode(), sb.toString(), appCode);
            } else {
                userTaskDetailDao.addHasExecutedTask(TaskTypeEnum.PUSH_DATA_TO_AD_JUST, TaskStatusEnum.INIT, JSONObject.toJSONString(pushData), "Waiting", eventType.getEventCode(), sb.toString(), appCode);
            }

        } catch (Exception e) {
            userTaskDetailDao.addHasExecutedTask(TaskTypeEnum.PUSH_DATA_TO_AD_JUST, TaskStatusEnum.FAILED, JSONObject.toJSONString(pushData), "Failed", eventType.getEventCode(), sb.toString(), appCode);
            logger.error("PushDataToAppsFlyerFailed, pushType:{}, pushData:{}", eventType.getEventCode(), JSONObject.toJSONString(pushData), e);
        }
        return Response.ok();
    }

    @Override
    public Response queryOrStoreIfNotExists(AdJustUserMappingReq request) {
        logger.info("queryOrStoreIfNotExists1, request:{}", JSONObject.toJSONString(request));
        if (Objects.isNull(request)) {
            return Response.ok();
        }

        // 存在adid与userCode映射关系，直接返回
        final UserAdjustMappingEntity userMapping = userAdjustMappingDao.getUserMapping(request.getUserCode());
        if (Objects.nonNull(userMapping)) {
            return Response.ok(userAdjustMappingMapper.toDto(userMapping));
        }

        final UserAdjustMappingEntity latestRecord = userAdjustMappingDao.getByAdid(request.getAdid());

        // 更新user表中的adid字段，并推送注册信息到adjust
        setAfidAndPushData(request);

        if (latestRecord == null || StringUtils.isEmpty(latestRecord.getUserCode())) {
            // 设置关联关系
            setUserCodeForExistsRecord(request, latestRecord);
            return Response.ok(userAdjustMappingMapper.toDto(latestRecord));
        }

        return Response.ok();
    }

    private void setUserCodeForExistsRecord(AdJustUserMappingReq request, UserAdjustMappingEntity existsRecordWithNoUserCode) {
        if (existsRecordWithNoUserCode == null) {
            UserAdjustMappingEntity newRecord = new UserAdjustMappingEntity();
            newRecord.setAdId(request.getAdid());
            newRecord.setUserCode(request.getUserCode());
            newRecord.setChannel(request.getChannel());
            newRecord.setContent(request.getContent());
            newRecord.setCampaign(request.getCampaign());
            newRecord.setAdset(request.getAfAdset());
            newRecord.setAd(request.getAfAd());
            if (StringUtils.isNotEmpty(request.getChannel()) && !request.getChannel().equals("l1")) {
                newRecord.setDataCompleteFlag(1);
            }
            userAdjustMappingDao.insert(newRecord);
            return;
        }

        existsRecordWithNoUserCode.setUserCode(request.getUserCode());
        existsRecordWithNoUserCode.setDataCompleteFlag(0);
        if (StringUtils.isNotEmpty(request.getChannel())) {
            existsRecordWithNoUserCode.setAdId(request.getAdid());
            existsRecordWithNoUserCode.setChannel(request.getChannel());
            existsRecordWithNoUserCode.setContent(request.getContent());
            existsRecordWithNoUserCode.setCampaign(request.getCampaign());
            existsRecordWithNoUserCode.setAdset(request.getAfAdset());
            existsRecordWithNoUserCode.setAd(request.getAfAd());
            if (!request.getChannel().equals("l1")) {
                existsRecordWithNoUserCode.setDataCompleteFlag(1);
            }
        }
        userAdjustMappingDao.updateByPrimaryKey(existsRecordWithNoUserCode);
    }


    private void setAfidAndPushData(AdJustUserMappingReq request) {
        final UserEntity userEntity = userDao.selectByUserCode(request.getUserCode());
        if (userEntity == null) {
            return;
        }
        userEntity.setChannel(request.getChannel());
        userEntity.setAdId(request.getAdid());
//        if (userEntity.getRegisterDate() == null) {
//            userEntity.setRegisterDate(new Date());
//        }
        userDao.updateByPrimaryKey(userEntity);

        // 推送注册数据到appsFlyer
//        final HashMap<String, Object> pushData = Maps.newHashMap();
//        pushData.put("userCode", request.getUserCode());
//        asyncTraceEvent(AdjustEventDefType.Registration, pushData);
    }

    @Override
    public Response updateAdjustInfo(AdJustUserMappingReq request) {
        if (request == null || StringUtils.isEmpty(request.getAdid()) || StringUtils.isEmpty(request.getChannel())) {
            logger.error("updateAdjustInfo, requestIsEmpty, request:{}", JSONObject.toJSONString(request));
            return Response.ok();
        }
        final UserAdjustMappingEntity existsRecord = userAdjustMappingDao.getNoMappingUserByAdid(request.getAdid());
        if (existsRecord == null) {
            UserAdjustMappingEntity newRecord = new UserAdjustMappingEntity();
            newRecord.setAdId(request.getAdid());
            newRecord.setChannel(request.getChannel());
            newRecord.setContent(request.getContent());
            newRecord.setCampaign(request.getCampaign());
            newRecord.setAdset(request.getAfAdset());
            newRecord.setAd(request.getAfAd());
            userAdjustMappingDao.insert(newRecord);
            return Response.ok();
        }

        if (StringUtils.isEmpty(existsRecord.getChannel())|| "l1".equals(existsRecord.getChannel())) {
            existsRecord.setChannel(request.getChannel());
            existsRecord.setContent(request.getContent());
            existsRecord.setCampaign(request.getCampaign());
            existsRecord.setAdset(request.getAfAdset());
            existsRecord.setAd(request.getAfAd());
            userAdjustMappingDao.updateByPrimaryKey(existsRecord);
            // 更新channel
            userDao.updateChannel(request.getAdid(), request.getChannel());
            return Response.ok();
        }

        return null;
    }

    @Override
    public Response<Boolean> fetNewAccountFlag(String userCode) {
        final UserEntity userEntity = userDao.selectByUserCode(userCode);
        if (Objects.isNull(userEntity) || Objects.isNull(userEntity.getGmtCreate())) {
            return Response.ok(Boolean.FALSE);
        }
        String createAccountDate = DateUtil.format(userEntity.getGmtCreate(), DatePattern.PURE_DATE_PATTERN);
        final boolean isNewAccount = DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN).equalsIgnoreCase(createAccountDate);
        return Response.ok(isNewAccount);
    }

}
